<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To-do-List</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
        text-decoration: none;
        list-style: none;
    }
    
    html,
    body {
        height: 100%;
    }
    
    .mask {
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
        background-color: rgba(0, 0, 0, 0.5);
        display: none;
    }
    
    .popupBox {
        padding: 20px;
        background-color: #fff;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    
    .popupBox input {
        width: 400px;
        height: 36px;
        font-size: 28px;
        margin-bottom: 30px;
    }
    
    .popupBox button {
        font-size: 18px;
    }
    
    .popupBox li:last-of-type {
        display: flex;
        justify-content: space-around;
    }
    
    fieldset {
        padding: 10px;
    }
    
    fieldset li {
        margin-bottom: 5px;
    }
</style>

<body>
    <div id="app">
        <header>
            <input class="date" type="datetime-local" step="1" v-model="inpDate" />
            <input class="content" type="text" placeholder="请输入备忘事件" v-model.trim="inpContent" @keyUp.enter="addTolist" />
            <button @click="addTolist">新增</button>
        </header>
        <main>
            <fieldset>
                <legend>待完成事件:<span>{{waitArr.length}}</span>个</legend>
                <template v-for="item in waitArr">
                        <li :key="item.id">
                           <input type="checkbox" @change="changeStatus(item.id)"/>
                           <span>{{item.content}}</span>
                           <mark>{{formatDate(item)}}</mark>
                           <button @click="delItem(item.id)">删除</button>
                        </li>
                </template>
            </fieldset>
            <fieldset>
                <legend>已完成事件:<span>{{doneArr.length}}</span>个</legend>
                <template v-for="item in doneArr">
                        <li :key="item.id">
                           <input type="checkbox" disabled checked/>
                           <span>{{item.content}}</span>
                           <mark>{{formatDate(item)}}</mark>
                           <button @click="recoverItem(item.id)">恢复事件</button>
                           <button @click="delItem(item.id)">删除</button>
                        </li>
                </template>
            </fieldset>
            <fieldset>
                <legend>已过期事件:<span>{{expireArr.length}}</span>个</legend>
                <template v-for="item in expireArr">
                        <li :key="item.id">
                           <span>{{item.content}}</span>
                           <button @click="recoverItem(item.id)">恢复事件</button>
                           <button @click="delItem(item.id)">删除</button>
                        </li>
                </template>
            </fieldset>
        </main>
        <div class="mask" v-if="isMaskShow">
            <div class="popupBox">
                <ul>
                    <li><input type="datetime-local " step="1" v-model="popupInpDate" /></li>
                    <li><input v-model="popupInpContent" /></li>
                    <li>
                        <button @click="confirmRecover">恢复事件</button>
                        <button @click="cancelPopup">取消恢复</button>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</body>
<script src="./vue-2.4.0.js"></script>
<script>
    new Vue({
        el: "#app ",
        data: {
            eventArr: [],
            inpContent: " ",
            inpDate: " ",
            isMaskShow: false, // 弹窗是否展示
            popupInpContent: "",
            popupInpDate: "",
            popupId: "",
        },
        methods: {
            // 获取时间输入框和文本输入框中的内容，渲染到待完成事件中
            addTolist() {
                if (this.inpContent && this.inpDate) {
                    this.eventArr.unshift({
                        id: Date.now().toString(), // 获取当前的时间
                        content: this.inpContent,
                        expeirTime: new Date(this.inpDate).getTime(), //将时间输入框中的时间转化为时间对象
                        diffTime: new Date(this.inpDate).getTime() - Date.now(),
                        status: 1, // 定义待完成事件的状态值为1 ,已完成事件的状态值为2,已过期事件的状态值为3
                    });
                    // 清空输入框
                    this.inpDate = this.inpContent = "";
                } else {
                    alert("输入框内容不能为空");
                }
            },
            //时间转换格式
            formatDate(item) {
                // 判断当前时间差是否大于一天
                if (item.diffTime > 86400000) {
                    // 大于1天显示时间格式
                    return new Date(item.expeirTime).toLocaleString();
                } else { // 小于1天显示X时X分X秒
                    let dateObj = new Date(item.diffTime - 28800000);
                    return `${dateObj.getHours()}时${dateObj.getMinutes()}分${dateObj.getSeconds()}秒`;
                }
            },

            // 删除事件
            delItem(nowId) {
                this.eventArr = this.eventArr.filter(item => {
                    return item.id != nowId;
                })
            },

            // 状态变更事件
            changeStatus(nowId) {
                this.eventArr.forEach(item => {

                    item.id == nowId && (item.status = 2);
                });
            },

            // 恢复事件 恢复的都是已经完成的，所以循环遍历已经完成的
            recoverItem(nowId) {
                let itemInfo = this.eventArr.find(item => {
                    return item.id == nowId;
                });
                this.popupInpDate = new Date(itemInfo.expeirTime);
                this.popupInpContent = itemInfo.inpContent;
                tiis.popupId = item.id;
                this.isMaskShow = true;
            },
            // 取消恢复
            cancelPop() {
                this.popupInpContent = "";
                this.popupInpDate = "";
                this.isMaskShow = false;
            },
            confirmRecover() {
                if (new Date(this.popupInpDate).getTime() > Date.now() + 10000) {
                    this.todoArr.forEach(item => {
                        if (item.id == this.popupId) {
                            item.expireTime = new Date(this.popupInpDate).getTime();
                            item.content = this.popupInpContent;
                            item.status = 1;
                        }
                    });
                    this.cancelPopup();
                } else {
                    alert('请选择将来的时间');
                }
            },

        },
        // 计算属性
        computed: {

            waitArr() {
                return this.eventArr.filter(item => {

                    return item.status == 1;

                });
            },
            doneArr() {
                return this.eventArr.filter(item => {
                    return item.status == 2;
                });
            },
            expireArr() {
                return this.eventArr.filter(item => {
                    return item.status == 3;
                });
            },
        },
        watch: {
            eventArr: {
                handler: function() {
                    localStorage.setItem("eventArr", JSON.stringify(this.eventArr))
                },
                deep: true,
            },
        },
        created() {
            if (localStorage.getItem("eventArr")) {
                this.eventArr = JSON.parse(localStorage.getItem("eventArr"));
            }
        },
        mounted() {
            setInterval(() => {

                let nowTime = Date.now();
                this.eventArr.forEach(item => {
                    if (item.status == 1) {
                        if (new Date(item.expeirTime).getTime() - nowTime > 0) {
                            item.diffTime = new Date(item.expeirTime).getTime() - nowTime;
                        } else { // 设置为已过期
                            item.status = 3;
                        }
                    }
                })
            }, 1000)
        }

    });
</script>

</html>